<?php

namespace Streetlamp\exception;

use think\App;
use think\exception\Handle;
use think\Log;
use think\Request;
use think\Config;

/*
 * 重写Handle的render方法，实现自定义异常消息
 */

class ExceptionHandler extends Handle
{
    private $code;
    private $msg;
    private $errorCode;
    private $trace = [];

    protected $ignoreReport = [
        '\\think\\exception\\HttpException',
        '\\app\\lib\\exception\\LoginException',
        '\\app\\lib\\exception\\PolicyException',
    ];

    public function report(\Exception $exception)
    {
        if (!$this->isIgnoreReport($exception)) {
            // 收集异常数据
            $data = [
                'file'    => $exception->getFile(),
                'line'    => $exception->getLine(),
                'message' => $this->getMessage($exception),
                'code'    => $this->getCode($exception),
            ];
            $log  = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]";
            $log  .= "\r\n" . $exception->getTraceAsString();
            Log::record($log, 'error');
        }
    }

    public function render(\Exception $e)
    {
        // 如果是服务器未处理的异常，将http状态码设置为500，并记录日志
        if (Config::get('app_debug')) {

            // 调试状态下需要显示TP默认的异常页面，因为TP的默认页面
            // 很容易看出问题
            //                return parent::render($e);
            $data['trace'] = [
                'name'   => get_class($e),
                'file'   => $e->getFile(),
                'line'   => $e->getLine(),
                // 'trace'  => $exception->getTrace(),
                'source' => $this->getSourceCode($e),
                'tables' => [
                    'GET Data'              => $_GET,
                    'POST Data'             => $_POST,
                    'Files'                 => $_FILES,
                    'Cookies'               => $_COOKIE,
                    'Session'               => isset($_SESSION) ? $_SESSION : [],
                    'Server/Request Data'   => $_SERVER,
                    'Environment Variables' => $_ENV,
                    //                         'ThinkPHP Constants'    => $this->getConst(),
                ],
            ];
            $this->trace   = $data;
        }
        $this->code      = $this->getCode($e);
        $this->msg       = $this->getMessage($e);
        $this->errorCode = $this->getCode($e);
        $request         = Request::instance();
        $result          = [
            'msg'  => $this->msg,
            'code' => $this->code,
            'time' => time(),
        ];

        if (Config::get('app_debug')) {
            $result = array_merge($result, [
                'request_url' => $request = $request->url(),
                'trace'       => $this->trace,
            ]);
        }
        return json($result, 200);
    }

}